package geektime.spring.springbucks.waiterservice.controller;

import geektime.spring.springbucks.waiterservice.controller.request.NewCoffeeRequest;
import geektime.spring.springbucks.waiterservice.model.Coffee;
import geektime.spring.springbucks.waiterservice.service.CoffeeService;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;


@Controller
@RequestMapping("/coffee")
@Slf4j
public class CoffeeController {

  @Autowired
  private CoffeeService coffeeService;

//  @PostMapping(path = "/", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
//  @ResponseBody
//  @ResponseStatus(HttpStatus.CREATED)
//  public Coffee addCOffee(@Valid NewCoffeeRequest newCoffee, BindingResult result) {
//    if (result.hasErrors()) {
//      //这里先简单处理一下,后续讲到异常处理时会改
//      log.warn("Binding Errors: {}", result);
//      return null;
//    }
//    return coffeeService.saveCoffee(newCoffee.getName(), newCoffee.getPrice());
//  }


  @PostMapping(path = "/", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
  @ResponseBody
  @ResponseStatus(HttpStatus.CREATED)
  public Coffee addCOffeeWithoutBindingResult(@Valid NewCoffeeRequest newCoffee) {
    return coffeeService.saveCoffee(newCoffee.getName(), newCoffee.getPrice());
  }

  @PostMapping(path = "/", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
  @ResponseBody
  @ResponseStatus(HttpStatus.CREATED)
  public Coffee addJsonCOffeeWithoutBindingResult(@Valid @RequestBody NewCoffeeRequest newCoffee) {
    return coffeeService.saveCoffee(newCoffee.getName(), newCoffee.getPrice());
  }

  @PostMapping(path = "/", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  @ResponseBody
  @ResponseStatus(HttpStatus.CREATED)
  public List<Coffee> batchAddCoffee(@RequestParam("file") MultipartFile file) {
    List<Coffee> coffees = new ArrayList<>();
    if (!file.isEmpty()) {
      BufferedReader reader = null;

      try {
        reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
        String str;
        while ((str = reader.readLine()) != null) {
          String[] arr = StringUtils.split(str, " ");
          if (arr != null && arr.length == 2) {
            Coffee coffee = coffeeService.saveCoffee(arr[0],
                Money.of(CurrencyUnit.of("CNY"), NumberUtils.createBigDecimal(arr[1])));
            coffees.add(coffee);
          }
        }
      } catch (IOException e) {
        log.error("exception", e);
      } finally {
        IOUtils.closeQuietly(reader);
      }
    }
    return coffees;
  }


  @GetMapping(path = "/", params = "!name")
  @ResponseBody
  public List<Coffee> getAll() {
    return coffeeService.getAllCoffee();
  }

  @RequestMapping(path = "/{id}", method = RequestMethod.GET)
  @ResponseBody
  public Coffee getById(@PathVariable Long id) {
    Coffee coffee = coffeeService.getCoffee(id);
    log.info("Coffee {};",coffee);
    return coffee;
  }

  @GetMapping(path = "/", params = "name")
  @ResponseBody
  public Coffee getByName(@RequestParam String name) {
    return coffeeService.getCoffee(name);
  }
}
